/**
 * @作者 faner
 * @创建时间 2021/2/25 18:41
 */
package com.faner.fast.activiti.service.impl;

import com.faner.fast.activiti.service.ProcessService;
import com.faner.fast.upms.util.FastSecurityUtils;
import lombok.RequiredArgsConstructor;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;

@Service
@Transactional
@RequiredArgsConstructor
public class ProcessServiceImpl implements ProcessService {


    private TaskService taskService;
    private HistoryService historyService;
    private RuntimeService runtimeService;
    /**
     * 提交申请
     */
    @Override
    public <T> void submitApply(T entity, String key) throws Exception {
        this.submitApply(entity, key, null);
    }

    @Override
    public <T> void submitApply(T entity, String key, Map<String, Object> variables) throws Exception {
        Class clazz = entity.getClass();

        Method getId = clazz.getDeclaredMethod("getId");
        Long id = (Long) getId.invoke(entity);

        Method setApplyUserId = clazz.getDeclaredMethod("setApplyUserId", String.class);
        Method setApplyUserName = clazz.getDeclaredMethod("setApplyUserName", String.class);
        Method setApplyTime = clazz.getDeclaredMethod("setApplyTime", Date.class);
        Method setProcessKey = clazz.getDeclaredMethod("setProcessKey", String.class);

        Method setUpdateBy = clazz.getSuperclass().getSuperclass().getDeclaredMethod("setUpdateBy", String.class);
        Method setUpdateTime = clazz.getSuperclass().getSuperclass().getDeclaredMethod("setUpdateTime", Date.class);

        Method setInstanceId = clazz.getDeclaredMethod("setInstanceId", String.class);

        String username = FastSecurityUtils.getUser().getUsername();
        String nickName = FastSecurityUtils.getUser().getUsername();
        Date now = new Date();

        // 更新流程通用字段
        setApplyUserId.invoke(entity, username);
        setApplyUserName.invoke(entity, nickName);
        setApplyTime.invoke(entity, now);
        setProcessKey.invoke(entity, key);
        setUpdateBy.invoke(entity, username);
        setUpdateTime.invoke(entity, now);

//        // 用来设置启动流程的人员ID，引擎会自动把用户ID保存到activiti:initiator中
//        identityService.setAuthenticatedUserId(username);
        // 启动流程时设置业务 key
        ProcessInstance instance = runtimeService.startProcessInstanceByKey(key, id + "", variables);

        // 更新业务表流程实例id字段
        setInstanceId.invoke(entity, instance.getId());

//        // 记录流程实例业务关系
//        InstanceBusiness ib = new InstanceBusiness();
//        ib.setInstanceId(instance.getId());
//        ib.setBusinessKey(id + "");
//        ib.setModule(humpToLine(entity.getClass().getSimpleName()).substring(1));
//        taskMapper.insertInstanceBusiness(ib);
    }

    @Override
    public <T> void richProcessField(T entity) throws Exception {

    }

    @Override
    public void complete(String taskId, String instanceId, String variables) {

    }

    @Override
    public void delegate(String taskId, String fromUser, String delegateToUser) {

    }

    @Override
    public void cancelApply(String instanceId, String deleteReason) {

    }

    @Override
    public void suspendOrActiveApply(String instanceId, String suspendState) {

    }
}
